package basic.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class ThreadBestPractice {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executor = new ThreadPoolExecutor(5, 10, 0, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>());
        futureTask(executor);
        completionService(executor);
        completableFuture(executor);
        executor.shutdown();
    }

    private static void futureTask(ExecutorService executor) throws ExecutionException, InterruptedException {
        List<Future> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            final int taskId = i;
            list.add(executor.submit(() -> System.out.println("Task " + taskId + " completed")));
        }
        for (Future future : list) {
            future.get();
        }
        System.out.println("Finished.");
    }

    private static void completionService(ExecutorService executor) throws InterruptedException, ExecutionException {
        CompletionService completionService = new ExecutorCompletionService<>(executor);
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            completionService.submit(() -> taskId);
        }
        for (int i = 0; i < 5; i++) {
            Future<Integer> completedTask = completionService.take();
            int result = completedTask.get();
            System.out.println("Task " + result + " completed");
        }
    }

    private static void completableFuture(ExecutorService executor) {
        CompletableFuture.runAsync(() -> {System.out.println("CompletableFuture");}, executor);
    }
}
